package org.tamal.classinfo;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.Arrays;

/**
 * This Class Represent a single BootstrapMethod of
 * {@link Attribute#BOOTSTRAP_METHODS} attribute.
 *
 * @author Tamal Kanti Nath
 */
public final class BootstrapMethod {
    private final ClassInfo cls;
    private int methodIndex;
    private final int[] arguments;

    private BootstrapMethod(DataInputStream in, ClassInfo cls)
        throws IOException {
        this.cls = cls;
        methodIndex = in.readUnsignedShort();
        arguments = new int[in.readUnsignedShort()];
        for (int i = 0; i < arguments.length; ++i) {
            arguments[i] = in.readUnsignedShort();
        }
    }

    /**
     * Returns bootstrap method.
     * @return the method
     */
    public int getMethodIndex() {
        return methodIndex;
    }

    /**
     * Returns bootstrap method.
     * @return the method
     */
    public String getMethod() {
        return cls.getPool()[methodIndex].toString();
    }

    /**
     * Returns bootstrap argument indexes.
     * @return the argument indexes
     */
    public int[] getArgumentIndexes() {
        return arguments;
    }

    /**
     * Returns bootstrap arguments.
     * @return the arguments
     */
    public String[] getArguments() {
        String[] args = new String[arguments.length];
        for (int i = 0; i < args.length; ++i) {
            args[i] = cls.getPool()[arguments[i]].toString();
        }
        return args;
    }

    @Override
    public String toString() {
        return getMethod() + Arrays.toString(getArguments());
    }

    /**
     * Reads BootstrapMethods from DataInputStream.
     * @param in the DataInputStream
     * @param cls The ClassInfo reference
     * @return the array of InnerClass
     * @throws IOException exception
     * @see Attribute
     */
    static BootstrapMethod[] readBootstrapMethods(DataInputStream in,
        ClassInfo cls) throws IOException {
        BootstrapMethod[] methods = new BootstrapMethod[in.readUnsignedShort()];
        for (int i = 0; i < methods.length; ++i) {
            methods[i] = new BootstrapMethod(in, cls);
        }
        return methods;
    }
}
